#ifndef ACEMESH_STACK_H
#define ACEMESH_STACK_H
#include "task.h"
#include "am_machine.h"

struct concurrent_aceMesh_stack
{
#ifdef CENTRAL_FIFO
    struct task* head_ptr;
    struct task* tail_ptr;
#else
    struct task* task_pool;
#endif
    volatile int my_lock;	
};

#if defined( _CIRCULAR_QUEUE)
#define CIRCULAR_ARRAY_SIZE 3800  //TODO:just experimental! can be adjusted dynamically later.
#define TASKCHUNK_UP 8
#define TASKCHUNK_DN 8
struct aceMesh_stack{
  struct task* base[CIRCULAR_ARRAY_SIZE]__attribute__((aligned(32))); //32Bytes aligned.
  int top,bottom; //cyclic array
};
#else
struct aceMesh_stack {
  struct task* task_pool; //top
};
#endif

void push(struct concurrent_aceMesh_stack* self,struct  task* t);
void init_push(struct concurrent_aceMesh_stack* self,struct  task* t);
int try_pop(struct concurrent_aceMesh_stack* self,struct task** t); 
#ifdef _CIRCULAR_QUEUE
void slave_push(struct task** base, struct  task* t);
int slave_try_pop(struct task** base,struct task** t); 
#else
void slave_push(struct concurrent_aceMesh_stack* self,struct task* t);
int slave_try_pop(struct concurrent_aceMesh_stack* self, struct task** t); 
#if defined( ASYN_INSERT_Q ) 
int slave_concur_try_pop(struct concurrent_aceMesh_stack* self,struct task** t);
#endif
#endif

/*



#if defined( _CIRCULAR_QUEUE)

#ifdef MASTER
void push(struct concurrent_aceMesh_stack* self,struct task* t);
void slave_push_to_master(struct concurrent_aceMesh_stack* self,struct task* t);
int try_pop(struct concurrent_aceMesh_stack* self, struct task** t); 
void push_to_slave(struct aceMesh_stack* self,struct task* t);
#else
void push(struct aceMesh_stack* self,struct task* t);
#endif
void slave_push(struct task** base, struct  task* t);
int slave_try_pop(struct task** base,struct task** t); 

void slave_bulkspill(struct task** base);
int slave_try_bulkpop(struct task** base); 

//#elif defined( _SERIAL_QUEUE)
#else

#ifdef MASTER
void push(struct concurrent_aceMesh_stack* self,struct task* t);
void slave_push_to_master(struct concurrent_aceMesh_stack* self,struct task* t);
int try_pop(struct concurrent_aceMesh_stack* self, struct task** t); 
void push_to_slave(struct aceMesh_stack* self,struct task* t);
#else
void push(struct aceMesh_stack* self,struct task* t);
#endif
void slave_push(struct aceMesh_stack* self,struct task* t);
int slave_try_pop(struct aceMesh_stack* self, struct task** t); 



#ifdef SEG_BUFF
//基于主存状态变量的主从异步并行支持
#define PENDING_BUFF_SIZE 2048
#define BUFF_SIZE 512

#ifdef ARRAY_STACK
struct aceMesh_stack
{
    struct task* base[PENDING_BUFF_SIZE]__attribute__((aligned(64))); //32Bytes aligned.
    int top; 
};
#else
struct aceMesh_stack{
    struct task* task_pool; //top
};
#endif

void push(struct concurrent_aceMesh_stack* self,struct  task* t);
int try_pop(struct concurrent_aceMesh_stack* self,struct task** t); 
void slave_push(struct concurrent_aceMesh_stack* self,struct task* t);
int slave_try_pop(struct concurrent_aceMesh_stack* self, struct task** t); 



#else




//struct concurrent_aceMesh_stack concurrent_aceMesh_stack_constructor();
void push(struct concurrent_aceMesh_stack* self,struct task* t);
void slave_push(struct concurrent_aceMesh_stack* self,struct task* t);

int try_push(struct concurrent_aceMesh_stack* self,struct  task* t); 
int slave_try_push(struct concurrent_aceMesh_stack* self, struct task* t); 

void slave_pop(struct task** t);
int slave_try_pop(struct concurrent_aceMesh_stack* self, struct task** t); 
int slave_empty();
//int try_pop(struct concurrent_aceMesh_stack* self, struct task** t); 
#endif //end of  SEG_BUFF


#endif

*/









#ifdef MASTER
#ifdef MPI_SURPPORT
struct aceMesh_queue
{
    struct task* head;
    struct task* tail;
};
//struct aceMesh_queue aceMesh_queue_constructor();
void q_push(struct aceMesh_queue* self ,struct task* t);
int try_q_pop(struct aceMesh_queue* self, struct task* t);

#ifdef MTEST_LIGHT
struct mtest_queue
{
    struct mtest_task* head;
    struct mtest_task* tail;
};
//struct aceMesh_queue aceMesh_queue_constructor();
void q_push_mtest(struct mtest_queue* self ,struct mtest_task* t);
int try_q_pop_mtest(struct mtest_queue* self, struct mtest_task* t);
#endif
#endif
#endif







#ifdef SEG_BUFF
#ifdef ARRAY_STACK
void copy_task_queue(struct aceMesh_stack* src, struct aceMesh_stack* dest);
void ser_push(struct aceMesh_stack* self,struct task* t);
int ser_try_pop(struct aceMesh_stack* self, struct task** t); 
#endif
void slave_ser_push(struct aceMesh_stack* self,struct task* t);
int slave_ser_try_pop(struct aceMesh_stack* self, struct task** t); 
#endif
#endif
